<template>
  <div 
    class="relative border-2 border-dashed rounded-lg p-6 transition-all duration-300 hover:border-primary-500 hover:bg-primary-50"
    :class="{
      'border-primary-500 bg-primary-50': isDragging,
      'border-red-500': errorMsg,
      'border-green-500': uploadSuccess && !uploading
    }"
    @dragover.prevent="handleDragOver"
    @dragleave.prevent="handleDragLeave"
    @drop.prevent="handleDrop"
  >
    <!-- 上传触发按钮 -->
    <label class="cursor-pointer block text-center">
      <input
        type="file"
        class="hidden"
        :accept="acceptTypes"
        @change="handleFileChange"
      />
      <div class="flex flex-col items-center justify-center gap-2 text-gray-600">
        <svg
          class="w-10 h-10 text-gray-400"
          fill="none"
          stroke="currentColor"
          viewBox="0 0 24 24"
          xmlns="http://www.w3.org/2000/svg"
        >
          <path
            stroke-linecap="round"
            stroke-linejoin="round"
            stroke-width="2"
            d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
          ></path>
        </svg>
        <p class="text-sm">点击上传文件</p>
        <p class="text-xs text-gray-400">
          支持格式：{{ fileTypeDesc }} | 最大大小：{{ maxSize }}MB
        </p>
      </div>
    </label>

    <!-- 上传状态提示 -->
    <div v-if="uploading" class="absolute top-4 right-4 flex items-center gap-1 text-sm text-primary-600">
      <svg class="w-4 h-4 animate-spin" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
      </svg>
      上传中...
    </div>

    <!-- 上传成功提示 -->
    <div v-if="uploadSuccess && !uploading" class="absolute top-4 right-4 flex items-center gap-1 text-sm text-green-600">
      <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
      </svg>
      上传成功
    </div>

    <!-- 错误提示 -->
    <div v-if="errorMsg" class="absolute top-4 right-4 text-sm text-red-500">{{ errorMsg }}</div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';
import { uploadFile } from '@/apis/upload'; // 请确保接口路径正确

const props = defineProps({
  // 允许的文件类型（例如：['image/jpeg', 'image/png'] 或 '.jpg,.png'）
  fileTypes: {
    type: Array,
    default: () => ['image/jpeg', 'image/png', 'application/pdf'],
  },
  // 最大文件大小（MB）
  maxSize: {
    type: Number,
    default: 5,
    validator: (val) => val > 0, // 确保最大值为正数
  },
  // 后端接收文件的字段名（关键修复：可配置）
  fileField: {
    type: String,
    default: 'file',
  },
  // 成功状态自动清除时间（秒）
  successClearTime: {
    type: Number,
    default: 3,
  },
});

const emit = defineEmits(['success', 'error', 'progress']);

// 状态管理（新增拖拽状态）
const uploading = ref(false);
const uploadSuccess = ref(false);
const errorMsg = ref('');
const isDragging = ref(false);

// 计算属性：文件选择器accept属性值（修复MIME和后缀名混合场景）
const acceptTypes = computed(() => {
  return props.fileTypes.map(type => {
    // 后缀名转MIME兼容格式（如 .pdf 转 application/pdf）
    if (type.startsWith('.')) {
      const ext = type.slice(1);
      return ext === 'pdf' ? 'application/pdf' : 
             ext.match(/^(jpg|jpeg|png|gif)$/) ? `image/${ext}` : type;
    }
    return type;
  }).join(',');
});

// 计算属性：文件类型描述文本（优化显示）
const fileTypeDesc = computed(() => {
  return props.fileTypes.map(type => {
    if (type.startsWith('.')) return type.slice(1).toUpperCase();
    if (type.startsWith('image/')) return `${type.split('/')[1].toUpperCase()}图片`;
    if (type === 'application/pdf') return 'PDF文件';
    if (type.startsWith('application/')) return `${type.split('/')[1].toUpperCase()}文件`;
    return type;
  }).join('、');
});

// 处理文件选择
const handleFileChange = (e) => {
  const file = e.target.files[0];
  if (file) validateAndUpload(file);
  e.target.value = ''; // 重置文件选择器，允许重复选择同一文件
};

// 处理拖拽覆盖（新增视觉反馈）
const handleDragOver = () => {
  isDragging.value = true;
  errorMsg.value = '';
  uploadSuccess.value = false;
};

// 处理拖拽离开（重置样式）
const handleDragLeave = () => {
  isDragging.value = false;
};

// 处理拖拽上传
const handleDrop = (e) => {
  isDragging.value = false;
  const file = e.dataTransfer.files[0];
  if (file) validateAndUpload(file);
};

// 验证并上传文件（核心逻辑修复）
const validateAndUpload = async (file) => {
  // 重置状态
  uploading.value = false;
  uploadSuccess.value = false;
  errorMsg.value = '';

  // 1. 验证文件类型（修复混合类型验证逻辑）
  const isTypeValid = props.fileTypes.some(type => {
    if (type.startsWith('.')) {
      // 后缀名匹配（忽略大小写）
      return file.name.toLowerCase().endsWith(type.toLowerCase());
    } else {
      // MIME类型匹配（处理文件MIME可能不准确的情况）
      return file.type === type || file.name.toLowerCase().endsWith(`.${type.split('/')[1]}`);
    }
  });

  if (!isTypeValid) {
    errorMsg.value = `不支持该文件类型，仅支持${fileTypeDesc.value}`;
    emit('error', new Error(errorMsg.value));
    return;
  }

  // 2. 验证文件大小（修复浮点数精度问题）
  const maxSizeBytes = props.maxSize * 1024 * 1024; // 转换为字节
  if (file.size > maxSizeBytes) {
    errorMsg.value = `文件大小超过${props.maxSize}MB限制（当前${(file.size / 1024 / 1024).toFixed(2)}MB）`;
    emit('error', new Error(errorMsg.value));
    return;
  }

  // 3. 上传文件（优化错误处理和字段名配置）
  try {
    uploading.value = true;
    const formData = new FormData();
    formData.append(props.fileField, file); // 使用可配置的字段名

    // 支持上传进度（新增功能）
    const res = await uploadFile(formData, {
      onUploadProgress: (progressEvent) => {
        const progress = Math.round((progressEvent.loaded / progressEvent.total) * 100);
        emit('progress', progress);
      }
    });

    // 验证接口返回格式
    if (!res.data?.fileName || !res.data?.url) {
      throw new Error('上传成功，但返回数据格式不正确');
    }

    uploadSuccess.value = true;
    emit('success', res.data);

    // 自动清除成功状态
    setTimeout(() => uploadSuccess.value = false, props.successClearTime * 1000);
  } catch (err) {
    errorMsg.value = err.message || '网络异常，上传失败，请重试';
    emit('error', err);
  } finally {
    uploading.value = false;
    isDragging.value = false; // 确保拖拽状态重置
  }
};
</script>